package com.codefish.codefishseckill.controller;

import com.codefish.codefishseckill.entity.SecKillGoods;
import com.codefish.codefishseckill.entity.User;
import com.codefish.codefishseckill.exception.GlobalException;
import com.codefish.codefishseckill.service.GoodsService;
import com.codefish.codefishseckill.service.SecKillGoodsService;
import com.codefish.codefishseckill.service.impl.RedisService;
import com.codefish.codefishseckill.utils.SecurityUtils;
import com.codefish.codefishseckill.utils.model.PageInfo;
import com.codefish.codefishseckill.utils.threadlocal.PageInfoThreadLocal;
import com.codefish.codefishseckill.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 商品相关控制器类
 *
 * @author codefish
 * @version 1.0
 * @date 2022/07/05 下午 05:42
 */
@Controller
@RequestMapping("/goods")
public class GoodsController {
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private SecKillGoodsService secKillGoodsService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ThymeleafViewResolver thymeleafViewResolver;
    @Autowired
    private RedisService redisService;

    public static final String VIEW_GOODS_TOLIST_REDIS_KEY = "view:goods:toList";
    public static final String SEC_GOODS_DETAIL_REDIS_KEY_PREFIX = "seckill:goods:";


//    @GetMapping("/toList")
//    @ResponseBody
//    public String toList(Model model, HttpServletRequest request, HttpServletResponse response) {
//
//        // 首先从redis缓存中获取页面
//        String html = (String) redisTemplate.opsForValue().get(VIEW_GOODS_TOLIST_REDIS_KEY);
//        if (!StringUtils.isEmpty(html)) {
//            return html;
//        }
//        //未命中redis，开始渲染页面
//        List<GoodsVO> goodsList = goodsService.listAllGoodsInfo();
//        model.addAttribute("goodsList", goodsList);
//
//        html = thymeleafViewResolver.getTemplateEngine().process("goodsList", new WebContext(request, response, request.getServletContext(), request.getLocale(), model.asMap()));
//        // return "goodsList";
//        //将渲染完成的页面存入redis，ttl为60s
//        redisTemplate.opsForValue().set(VIEW_GOODS_TOLIST_REDIS_KEY, html, 60, TimeUnit.SECONDS);
//        return html;
//    }


    @GetMapping("/toList")
    public String toList(Model model) {
        PageInfo pageInfo = PageInfoThreadLocal.get();
        List<GoodsVO> goodsList = goodsService.listAllGoodsInfo(pageInfo);

        model.addAttribute("goodsList", goodsList);
        model.addAttribute("pageInfo", pageInfo);

        return "goodsList";
    }

    @GetMapping("/rest/toList")
    @ResponseBody
    public RespBean toList() {
        PageInfo pageInfo = PageInfoThreadLocal.get();
        List<GoodsVO> goodsList = goodsService.listAllGoodsInfo(pageInfo);

        Map<String, Object> result = new HashMap<String, Object>();
        result.put("goodsList", goodsList);
        result.put("pageInfo", pageInfo);

        return RespBeanFactory.success("查询成功", result);
    }


    @GetMapping("/goodsDetail")
    public String goodsDetail(@RequestParam Long goodsId, Model model, HttpSession session) {
        if (goodsId == null) {
            throw new GlobalException(RespBeanFactory.denied("goodsId不能为空"));
        }
        SecGoodsDetailVO goods = goodsService.getSecGoodsById(goodsId);
        model.addAttribute("goods", goods);


//        判断当前时间是否在抢购时间内
        int secKillStatus = 0;
        if (System.currentTimeMillis() < goods.getStartTime().getTime()) {
            int remainSeconds = (int) (goods.getStartTime().getTime() - System.currentTimeMillis()) / 1000;
            model.addAttribute("remainSeconds", remainSeconds);
        } else if (System.currentTimeMillis() < goods.getEndTime().getTime()) {
            model.addAttribute("remainSeconds", 0);
            secKillStatus = 1;
        } else {
            model.addAttribute("remainSeconds", -1);
            secKillStatus = 2;
        }
        //获取用户身份
        User user = SecurityUtils.getLocalUser().getUser();
        //生成接口地址动态路径变量
        String path = secKillGoodsService.getPath(user, goodsId);
        model.addAttribute("path", path);
        model.addAttribute("secKillStatus", secKillStatus);
        return "goodsDetail";
    }


    @GetMapping("/rest/goodsDetail")
    @ResponseBody
    public RespBean goodsDetailRestful(@RequestParam Long goodsId) {

        if (goodsId == null) {
            throw new GlobalException(RespBeanFactory.denied("goodsId不能为空"));
        }

        //首先从redis中查找goodsId对应的商品是否存在

        // GoodDetailDTO goodDetailDTO = new GoodDetailDTO();
        GoodDetailDTO goodDetailDTO = (GoodDetailDTO) redisTemplate.opsForValue().get(SEC_GOODS_DETAIL_REDIS_KEY_PREFIX + goodsId);
        if (goodDetailDTO != null) {
            return RespBeanFactory.success("获取商品信息成功", goodDetailDTO);
        }

        //从redis中找不到，则从数据库查找
        goodDetailDTO = new GoodDetailDTO();
        SecGoodsDetailVO goods = goodsService.getSecGoodsById(goodsId);
        if (goods == null) {
            return RespBeanFactory.fail("商品不存在");
        }
        goodDetailDTO.setGoods(goods);

//        判断当前时间是否在抢购时间内
        int secKillStatus = 0;
        if (System.currentTimeMillis() < goods.getStartTime().getTime()) {
            int remainSeconds = (int) (goods.getStartTime().getTime() - System.currentTimeMillis()) / 1000;
            goodDetailDTO.setRemainSeconds(remainSeconds);
        } else if (System.currentTimeMillis() < goods.getEndTime().getTime()) {
            goodDetailDTO.setRemainSeconds(0);
            secKillStatus = 1;
        } else {
            goodDetailDTO.setRemainSeconds(-1);
            secKillStatus = 2;
        }
        goodDetailDTO.setSecKillStatus(secKillStatus);

        //存入redis，设置过期时间60min
        redisTemplate.opsForValue().set(SEC_GOODS_DETAIL_REDIS_KEY_PREFIX + goodsId, goodDetailDTO, 60, TimeUnit.MINUTES);

        return RespBeanFactory.success("获取商品信息成功", goodDetailDTO);
    }


    @GetMapping("/goodsDetail/update")
    public String updateGoodDetail(@RequestParam Long goodsId, Model model) {
        if (goodsId == null) {
            throw new GlobalException(RespBeanFactory.fail("无效的商品编号"));
        }
        SecGoodsDetailVO goods = goodsService.getSecGoodsById(goodsId);
        if (goods == null) {
            throw new GlobalException(RespBeanFactory.fail("商品不存在"));
        }
        model.addAttribute("goods", goods);
        return "GoodsEdit";
    }

    //修改秒杀商品信息
    @PostMapping("/goodsDetail/update")
    public String updateGoodDetail(@ModelAttribute SecKillGoods goods) {
        //数据库更新
        boolean res = secKillGoodsService.updateByGoodsId(goods);
        if (!res) {
            throw new GlobalException(RespBeanFactory.fail("更新失败"));
        }
        //更新成功后从redis移除商品信息，保持数据一致性
        redisService.deleteKey(SEC_GOODS_DETAIL_REDIS_KEY_PREFIX + goods.getGoodsId());
        //调用延时删除API
        redisService.deleteKeyDelay(SEC_GOODS_DETAIL_REDIS_KEY_PREFIX + goods.getGoodsId());

        return "redirect:/goods/goodsDetail/update?goodsId=" + goods.getGoodsId();
    }


    //修改秒杀商品信息（rest调用）
    @PostMapping("/rest/goodsDetail/update")
    @ResponseBody
    public RespBean updateGoodDetailRestFul(SecKillGoods goods) {
        //数据库更新
        boolean res = secKillGoodsService.updateByGoodsId(goods);
        if (!res) {
            throw new GlobalException(RespBeanFactory.fail("更新失败"));
        }
        //更新成功后从redis移除商品信息，保持数据一致性
        redisService.deleteKey(SEC_GOODS_DETAIL_REDIS_KEY_PREFIX + goods.getGoodsId());
        //调用延时删除API
        redisService.deleteKeyDelay(SEC_GOODS_DETAIL_REDIS_KEY_PREFIX + goods.getGoodsId());

        return RespBeanFactory.success("商品信息修改成功", goods);
    }

}
